home *** CD-ROM | disk | FTP | other *** search
/ Programming Sound Cards / Programming Sound Cards.iso / sound_85 / sbvoice.pas < prev   
Pascal/Delphi Source File  |  1995-01-01  |  10KB  |  328 lines

  1. {---------------------------------------------------------------------------
  2.                    Unit SBVoice (v1.00) for Turbo Pascal 6.0
  3.        For interfacing with the SoundBlaster's digitized voice channel.
  4.            Copyright (c) 1991, Amit K. Mathur, Windsor, Ontario.
  5.  
  6.                         By: Amit K. Mathur
  7.                             3215 St. Patrick's Drive
  8.                             Windsor, Ontario
  9.                             N9E 3H2 CANADA
  10.                         Ph: (519) 966-6924
  11.  
  12.  Networks:  RIME(tm) R/O ->WINDSOR, ILink (Shareware), NA-Net (Gaming),
  13.             WWIVNet (#198@5950), or direct on NorthSTAR (519)735-1504.
  14.  
  15.  These routines are released to the public domain.  However I will gladly
  16.  accept contributions towards further development of this and other products.
  17.  Please send any changes or improvements my way.  And I'm interested in
  18.  other SoundBlaster utilities and programming tools.  Thanks in advance.
  19.  --------------------------------------------------------------------------}
  20.  
  21. {$O+,F+}
  22. { Allow this Unit to Be Overlayed (doesn't affect compilation if you decide
  23.   not to overlay it), and force far calls.                                 }
  24.  
  25. unit SBVoice;
  26.  
  27. interface
  28.  
  29. uses MemAlloc;                                    { Memory Allocation Proc }
  30.  
  31. var  SoundFile: Array[1..25000] of byte;          { whatever size you want }
  32.      sgSBDriver, ofSBDriver: word;                { seg and ofs of Driver  }
  33.      SBDriver: Pointer;                           { pointer to the driver  }
  34.      StatusWord: Word;                            { stores SB status       }
  35.  
  36. procedure loaddriver(fi:string);
  37. { Loads CT-VOICE.DRV into memory.  'fi' is the path to the driver.         }
  38.  
  39. procedure closedriver;
  40. { Clean up routine.  Not really necessary if your program is over.         }
  41.  
  42. procedure loadvoice(f:string;start,size:word);
  43. { Load 'f' into memory.  Start is the start of the area within
  44.   'f' to load and size is the amount to laod.  If you set size to 0
  45.   then it will load the entire file.                                      }
  46.  
  47. function sb_getversion:integer;
  48. { Get the version number of the CT-VOICE.DRV
  49.   Returns the Version number                                              }
  50.  
  51. function sb_init:integer;
  52. { Initialize the SoundBlaster.  Call this right after load driver, unless
  53.   you have to change the BaseIOAddress or Interrupt number and haven't
  54.   changed the CT-VOICE.DRV file itself.
  55.   Returns:  0 - no problem
  56.             1 - sound card failiure
  57.             2 - I/O failiure
  58.             3 - DMA interrupt failiure                                    }
  59.  
  60. procedure sb_output(sg,os:word);
  61. { Output the digitized sound.  You must load the sound first!
  62.   sg and os are the segment and offset of either SoundFile or whatever
  63.   array you use to store the sound.  If you use a .VOC file then call
  64.   with 26 added to the offset.                                            }
  65.  
  66. procedure sb_setstatusword(sg,os:word);
  67. { Sets the location of the status word.  This is the third thing you should
  68.   do, after loading the driver and initializing it.
  69.   The StatusWord will contain $0FFFF if input/output is in output, and
  70.   0 when it's done.  It will also hold the values of the markers in voice
  71.   files if any are encounterred, allowing you to coordinate output with
  72.   your programs.                                                          }
  73.  
  74. procedure sb_speaker(mode:word);
  75. { Set the speaker on/off.  Off is mode 0, and On is anything else.  This
  76.   is the fourth thing you should do in your initialization.               }
  77.  
  78. procedure sb_uninstall;
  79. { Uninstall the driver from memory.   Used by CloseDriver.                }
  80.  
  81. procedure sb_setIOaddress(add:word);
  82. { Override the IOaddress found inside the CT-VOICE.DRV file.  Add is the
  83.   new IO address.                                                         }
  84.  
  85. procedure sb_setinterruptnumber(intno:word);
  86. { Allows you to override the Interrupt number in the driver.  IntNo is your
  87.   new interrupt number (3, 5, 7 or 9).                                    }
  88.  
  89. procedure sb_stopoutput;
  90. { Stops the output in progress                                            }
  91.  
  92. function sb_pauseoutput: integer;
  93. { Pauses the output in progress.
  94.   Returns:  0 - success
  95.             1 - fail                                                      }
  96.  
  97. function sb_continueoutput: integer;
  98. { Continues a paused output.
  99.   Returns:  0 - success
  100.             1 - fail (nothing to continue)                                }
  101.  
  102. function sb_breakloop(mode:word): integer;
  103. { Breaks out of the currect output loop.
  104.   Modes:  0 - continue round, stop when done
  105.           1 - stop immediately
  106.   Returns:  0 - success
  107.             1 - not in loop                                               }
  108.  
  109. procedure sb_input(highlength,lowlength,seginputbuff,ofsinputbuff:word);
  110. { Input digitized sound.
  111.   HighLength: The high byte of the length of the input buffer.
  112.   LowLength:  The low byte of the length of the input buffer.
  113.   SegInputBuff: The Segment of the start of the input buffer.
  114.   OfsInputBuff: The Offset of the start of the input buffer.              }
  115.  
  116. procedure sb_setuserfunction(segaddress,ofsaddress:word);
  117. { Sets up a user function that the SB calls when it encounters a new data
  118.   block.  It must perform a FAR ret, preserve DS,DI,SI and flag register.
  119.   Clear Carry flag if you want the driver to process the block, or set it
  120.   if your routine will.  It must be clear if the block type is 0, that
  121.   is the terminate block.
  122.   SegAddress is the segment of your user function in memory.
  123.   OfsAddress is the ofset of your user function in memory.                }
  124.   
  125. implementation
  126.  
  127. uses DOS;
  128.  
  129. procedure Abort(s:string);
  130. begin
  131.   writeln('The Following Error Has Occurred: ',s);
  132.   writeln('Remedy and try again.  We apologize for any inconvenience.');
  133.   halt(1);
  134. end;
  135.  
  136. procedure loaddriver(fi:string);
  137. var f: file;
  138.     k: integer;
  139.     t: string[8];
  140. begin
  141.     assign(f,fi+'CT-VOICE.DRV');
  142.     {$I-} Reset(f,1); {$I+}
  143.     if IOResult <> 0 then
  144.         Abort('Cannot Open '+fi+'CT-VOICE.DRV');
  145.     blockread(f,Mem[sgSBDriver:ofSBDriver],filesize(f));
  146.     close(f);
  147.     t:='';
  148.     for k:=0 to 7 do
  149.         t:=t+chr(Mem[sgSBDriver:ofSBDriver+k+3]);
  150.     if t<>'CT-VOICE' then
  151.         abort('Invalid CT-VOICE Driver!');
  152. end;
  153.  
  154. procedure closedriver;
  155. begin
  156.     sb_uninstall;
  157.     if dalloc(sbdriver)=0 then
  158.         abort('Uninstall Error!');
  159. end;
  160.  
  161. procedure loadvoice(f:string;start,size:word);
  162. var fi: file;
  163.     k: word;
  164. begin
  165.     assign(fi,f);
  166.     {$I-} Reset(fi,1); {$I+}
  167.     if IOResult <> 0 then
  168.        abort('Cannot Open '+f+'!');
  169.     k:=0;
  170.     seek(fi,start);
  171.     if size=0 then size:=filesize(fi);
  172.     blockread(fi,Mem[seg(soundfile):ofs(soundfile)],size);
  173.     close(fi);
  174. end;
  175.  
  176. function sb_getversion: integer; assembler;
  177. asm
  178.    push  bp
  179.    mov   bx,0
  180.    call  SBDriver
  181.    pop   bp
  182. end;
  183.  
  184. procedure sb_setIOaddress(add:word); assembler;
  185. asm
  186.    push  bp
  187.    mov   bx,1
  188.    mov   ax,add
  189.    call  SBDriver
  190.    pop   bp
  191. end;
  192.  
  193. procedure sb_setinterruptnumber(intno:word); assembler;
  194. asm
  195.    push  bp
  196.    mov   bx,2
  197.    mov   ax,intno
  198.    call  SBDriver
  199.    pop   bp
  200. end;
  201.  
  202. procedure sb_stopoutput; assembler;
  203. asm
  204.    push  bp
  205.    mov   bx,8
  206.    call  SBDriver
  207.    pop   bp
  208. end;
  209.  
  210. function sb_init: integer; assembler;
  211. asm
  212.    push  bp
  213.    mov   bx, 3
  214.    call  SBDriver
  215.    pop   bp
  216. end;
  217.  
  218. function sb_pauseoutput: integer; assembler;
  219. asm
  220.    push  bp
  221.    mov   bx,10
  222.    call  SBDriver
  223.    pop   bp
  224. end;
  225.  
  226. function sb_continueoutput: integer; assembler;
  227. asm
  228.    push  bp
  229.    mov   bx,11
  230.    call  SBDriver
  231.    pop   bp
  232. end;
  233.  
  234. function sb_breakloop(mode:word): integer; assembler;
  235. asm
  236.    push  bp
  237.    mov   bx,12
  238.    mov   ax,mode
  239.    call  SBDriver
  240.    pop   bp
  241. end;
  242.  
  243. procedure sb_output(sg,os:word); assembler;
  244. asm
  245.     push bp
  246.     push di
  247.     mov  bx,6
  248.     mov  di,os             { offset of voice  }
  249.     mov  es,sg             { segment of voice }
  250.     call SBDriver
  251.     pop  di
  252.     pop  bp
  253. end;
  254.  
  255. procedure sb_input(highlength,lowlength,seginputbuff,ofsinputbuff:word); assembler;
  256. asm
  257.     push bp
  258.     push di
  259.     mov  bx,7
  260.     mov  dx,highlength
  261.     mov  cx,lowlength
  262.     mov  es,seginputbuff
  263.     mov  di,ofsinputbuff
  264.     call SBDriver
  265.     pop  di
  266.     pop  bp
  267. end;
  268.  
  269. procedure sb_setstatusword(sg,os:word); assembler;
  270. asm
  271.     push bp
  272.     push di
  273.     mov  bx,5
  274.     mov  di,os
  275.     mov  es,sg
  276.     call SBDriver
  277.     pop  di
  278.     pop  bp
  279. end;
  280.  
  281. procedure sb_speaker(mode:word); assembler;
  282. asm
  283.    push  bp
  284.    mov   bx,4
  285.    mov   ax,mode
  286.    call  SBDriver
  287.    pop   bp
  288. end;
  289.  
  290. procedure sb_uninstall; assembler;
  291. asm
  292.    push  bp
  293.    mov   bx,9
  294.    call  SBDriver
  295.    pop   bp
  296. end;
  297.  
  298. procedure sb_setuserfunction(segaddress,ofsaddress:word); assembler;
  299. asm
  300.    push  bp
  301.    mov   dx,segaddress
  302.    mov   ax,ofsaddress
  303.    mov   bx,13
  304.    call  SBDriver
  305.    pop   bp
  306. end;
  307.  
  308.  
  309. begin {set up SB}
  310.  
  311.   If DOSMemAvail < 2500 then                           { lower the heap   }
  312.       abort('Not Enough Memory');                      { with $M to fix   }
  313.   StatusWord:=MAlloc(SBDriver,2500);
  314.   if StatusWord<>0 then
  315.       abort('Memory Allocation Error');
  316.  
  317.   sgSBDriver:=MemW[seg(SBDriver):ofs(SBDriver)+2];
  318.   ofSBDriver:=MemW[seg(SBDriver):ofs(SBDriver)];
  319.  
  320.   Loaddriver('d:\sb\drv\');                            { change at will   }
  321.   if sb_init<>0 then                                   { or stick in your }
  322.       abort('SoundBlaster Initialization Error!');     { own program init }
  323.  
  324.   sb_setstatusword(seg(statusword),ofs(statusword));   { see above        }
  325.   sb_speaker(1);                                       { again!           }
  326.  
  327. end.
  328.